/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using System.Collections.Generic;
using NetProtocol.POD;
using NetProtocol.Enum;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using IQIGame.Onigao.Framework;
using Cysharp.Threading.Tasks;
using System;
using static IQIGame.Onigao.Game.MessageWrapper;

namespace NetProtocol.Client {
	/// <summary>
	/// 皮肤模块
	/// module : skin
	/// </summary>
	public interface CNetSkin : INetClientModule {
		
		public ISession GetSession();
	
		Dictionary<int, INetClientModule.Package2MessageWrapper> INetClientModule.GetModuleFunction()
        {
            MessageFunction wearResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<WearResultData>)wrapper;
                SC_wearResult(session, ref _wrapper.message);
                MessageWrapperPool<WearResultData>.Put(_wrapper);
            };
            MessageFunction viewSkinResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<ViewSkinResultData>)wrapper;
                SC_viewSkinResult(session, ref _wrapper.message);
                MessageWrapperPool<ViewSkinResultData>.Put(_wrapper);
            };
            MessageFunction notifyUpdateSkin_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyUpdateSkinData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.skin_notifyUpdateSkin, "Recv->" + _wrapper.message.ToString());
#endif
                SC_notifyUpdateSkin(session, _wrapper.message.type, _wrapper.message.skin);
                MessageWrapperPool<NotifyUpdateSkinData>.Put(_wrapper);
            };
        
            Dictionary<int, INetClientModule.Package2MessageWrapper> retDic = new()
            {
                {NetMessageId.skin_wearResult, (session, package) => {
                	var result = MessageWrapperPool<WearResultData>.Get();
                	result.Init(session, wearResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.skin_viewSkinResult, (session, package) => {
                	var result = MessageWrapperPool<ViewSkinResultData>.Get();
                	result.Init(session, viewSkinResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.skin_notifyUpdateSkin, (session, package) => {
                	var result = MessageWrapperPool<NotifyUpdateSkinData>.Get();
                	result.Init(session, notifyUpdateSkin_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
            };
            return retDic;
        }
#region Client-side Interface
		/// <summary>
        /// 
        /// </summary>
		public void SC_wearResult(ISession session, ref WearResultData message) 
		{
            _SC_wearResult(session, ref message);
		}
		
		public void _SC_wearResult(ISession session, ref WearResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.skin_wearResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.skin_wearResult, message.code);
			MsgAsyncAwaiter<WearResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        /// 
        /// </summary>
		public void SC_viewSkinResult(ISession session, ref ViewSkinResultData message) 
		{
            _SC_viewSkinResult(session, ref message);
		}
		
		public void _SC_viewSkinResult(ISession session, ref ViewSkinResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.skin_viewSkinResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.skin_viewSkinResult, message.code);
			MsgAsyncAwaiter<ViewSkinResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        /// 通知时装更新 type=1获得，type=2更新，type=3删除
        /// </summary>
		protected void SC_notifyUpdateSkin(ISession session, int type, SkinPOD skin);
#endregion
#region Server-side Interface
		/// <summary>
        /// 穿着时装   
        /// </summary>
    	public UniTask<WearResultData> CS_wear(int skinCid)
        {
            return _CS_wear(skinCid);
        }
        
        public UniTask<WearResultData> _CS_wear(int skinCid)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(WearResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.skin_wear, "Send->"+"Skin.CS_wear { "
				+ "skinCid="
				+ skinCid
				+" }");
#endif
        	UniTask<WearResultData> task = MsgAsyncAwaiter<WearResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_wear(skinCid));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.skin_wearResult);
			return task;
        }
		
		public static SendPackage Pack_for_wear(int skinCid) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.skin_wear;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(skinCid);
			return si_p;
		}
		/// <summary>
        /// 查看时装
        /// </summary>
    	public UniTask<ViewSkinResultData> CS_viewSkin(int skinCid)
        {
            return _CS_viewSkin(skinCid);
        }
        
        public UniTask<ViewSkinResultData> _CS_viewSkin(int skinCid)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(ViewSkinResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.skin_viewSkin, "Send->"+"Skin.CS_viewSkin { "
				+ "skinCid="
				+ skinCid
				+" }");
#endif
        	UniTask<ViewSkinResultData> task = MsgAsyncAwaiter<ViewSkinResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_viewSkin(skinCid));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.skin_viewSkinResult);
			return task;
        }
		
		public static SendPackage Pack_for_viewSkin(int skinCid) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.skin_viewSkin;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(skinCid);
			return si_p;
		}
#endregion
#region Messages
        public struct WearResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.skin_wearResult;}
            
            public override string ToString()
            {
                return "Skin.wearResult"+ ", code="+ code;
            }
        }
        public struct ViewSkinResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.skin_viewSkinResult;}
            
            public override string ToString()
            {
                return "Skin.viewSkinResult"+ ", code="+ code;
            }
        }
        public struct NotifyUpdateSkinData : IReceiveMessage {
	        public int type;
	        public SkinPOD skin;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                type = _in.HasRemaining() ? _in.Read_int() : default;
                skin = _in.HasRemaining() ? _in.Read_pod<SkinPOD>(SkinPOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.skin_notifyUpdateSkin;}
            
            public override string ToString()
            {
                return "Skin.notifyUpdateSkin"+ ", type="+ type+ ", skin="+ skin;
            }
        }
    }
#endregion
}